home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / mail / pine3.96.tar.gz / pine3.96.tar / pine3.96 / imap / ANSI / c-client / os_dwa.c < prev    next >
C/C++ Source or Header  |  1995-09-09  |  10KB  |  367 lines

  1. /*
  2.  * Program:    Operating-system dependent routines -- DOS (Waterloo) version
  3.  *
  4.  * Author:    Mark Crispin
  5.  *        Networks and Distributed Computing
  6.  *        Computing & Communications
  7.  *        University of Washington
  8.  *        Administration Building, AG-44
  9.  *        Seattle, WA  98195
  10.  *        Internet: MRC@CAC.Washington.EDU
  11.  *
  12.  * Date:    11 April 1989
  13.  * Last Edited:    8 September 1995
  14.  *
  15.  * Copyright 1995 by the University of Washington
  16.  *
  17.  *  Permission to use, copy, modify, and distribute this software and its
  18.  * documentation for any purpose and without fee is hereby granted, provided
  19.  * that the above copyright notice appears in all copies and that both the
  20.  * above copyright notice and this permission notice appear in supporting
  21.  * documentation, and that the name of the University of Washington not be
  22.  * used in advertising or publicity pertaining to distribution of the software
  23.  * without specific, written prior permission.  This software is made
  24.  * available "as is", and
  25.  * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
  26.  * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
  27.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
  28.  * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
  29.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  30.  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
  31.  * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
  32.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  33.  *
  34.  */
  35.  
  36. #include <tcp.h>        /* must be before TCPSTREAM definition */
  37.  
  38.  
  39. /* TCP input buffer -- must be large enough to prevent overflow */
  40.  
  41. #define BUFLEN 8192
  42.  
  43.  
  44. /* TCP I/O stream (must be before osdep.h is included) */
  45.  
  46. #define TCPSTREAM struct tcp_stream
  47. TCPSTREAM {
  48.   char *host;            /* host name */
  49.   long port;            /* port number */
  50.   char *localhost;        /* local host name */
  51.   tcp_Socket *tcps;        /* tcp socket */
  52.   long ictr;            /* input counter */
  53.   char *iptr;            /* input pointer */
  54.   char ibuf[BUFLEN];        /* input buffer */
  55. };
  56.  
  57.  
  58. /* Private function prototypes */
  59.  
  60. #include "mail.h"
  61. #include "osdep.h"
  62. #include <time.h>
  63. #include <errno.h>
  64. #include <sys\timeb.h>
  65. #include "misc.h"
  66.  
  67. /* Undo compatibility definition */
  68.  
  69. #undef tcp_open
  70.  
  71. #include "fs_dos.c"
  72. #include "ftl_dos.c"
  73. #include "nl_dos.c"
  74. #include "env_dos.c"
  75.  
  76.  
  77. /* Global data */
  78.  
  79. short sock_initted = 0;        /* global so others using net can see it */
  80.  
  81.  
  82. /* Return my local host name
  83.  * Returns: my local host name
  84.  */
  85.  
  86. char *mylocalhost (void)
  87. {
  88.   if (!myLocalHost) {
  89.     char *s,hname[32],tmp[MAILTMPLEN];
  90.     long myip;
  91.  
  92.     if (!sock_initted++) sock_init();
  93.     tcp_cbrk (0x01);        /* turn off ctrl-break catching */
  94.     /*
  95.      * haven't discovered a way to find out the local host's 
  96.      * name with wattcp yet.
  97.      */
  98.     if (myip = gethostid ()) sprintf (s = tmp,"[%s]",inet_ntoa (hname,myip));
  99.     else s = "random-pc";
  100.     myLocalHost = cpystr (s);
  101.   }
  102.   return myLocalHost;
  103. }
  104.  
  105.  
  106. /* TCP/IP manipulate parameters
  107.  * Accepts: function code
  108.  *        function-dependent value
  109.  * Returns: function-dependent return value
  110.  */
  111.  
  112. void *tcp_parameters (long function,void *value)
  113. {
  114.   return NIL;
  115. }
  116.  
  117. /* TCP/IP open
  118.  * Accepts: host name
  119.  *        contact service name
  120.  *        contact port number
  121.  * Returns: TCP/IP stream if success else NIL
  122.  */
  123.  
  124. TCPSTREAM *TCP_open (char *host,char *service,long port)
  125. {
  126.   TCPSTREAM *stream = NIL;
  127.   tcp_Socket *sock;
  128.   char *s,tmp[MAILTMPLEN];
  129.   long adr,i,j,k,l;
  130.                 /* initialize if first time here */
  131.   if (!sock_initted++) sock_init();
  132.   if (s = strchr (host,':')) {    /* port number specified? */
  133.     *s++ = '\0';        /* yes, tie off port */
  134.     port = strtol (s,&s,10);    /* parse port */
  135.     if (s && *s) {
  136.       sprintf (tmp,"Junk after port number: %.80s",s);
  137.       mm_log (tmp,ERROR);
  138.       return NIL;
  139.     }
  140.   }
  141.   /* The domain literal form is used (rather than simply the dotted decimal
  142.      as with other Unix programs) because it has to be a valid "host name"
  143.      in mailsystem terminology. */
  144.                 /* look like domain literal? */
  145.   if (host[0] == '[' && host[strlen (host)-1] == ']') {
  146.     if (((i = strtol (s = host+1,&s,10)) <= 255) && *s++ == '.' &&
  147.     ((j = strtol (s,&s,10)) <= 255) && *s++ == '.' &&
  148.     ((k = strtol (s,&s,10)) <= 255) && *s++ == '.' &&
  149.     ((l = strtol (s,&s,10)) <= 255) && *s++ == ']' && !*s)
  150.       adr = (i << 24) + (j << 16) + (k << 8) + l;
  151.     else {
  152.       sprintf (tmp,"Bad format domain-literal: %.80s",host);
  153.       mm_log (tmp,ERROR);
  154.       return NIL;
  155.     }
  156.   }
  157.   else {            /* lookup host name */
  158.     if (!(adr = resolve (host))) {
  159.       sprintf (tmp,"Host not found: %s",host);
  160.       mm_log (tmp,ERROR);
  161.       return NIL;
  162.     }
  163.   }
  164.  
  165.                 /* OK to instantiate socket now */
  166.   sock = (tcp_Socket *) fs_get (sizeof (tcp_Socket));
  167.                 /* open connection */
  168.   if (!tcp_open (sock,(word) 0,adr,(word) port,NULL)) {
  169.     sprintf (tmp,"Can't connect to %.80s,%ld",host,port);
  170.     mm_log (tmp,ERROR);
  171.     fs_give ((void **) &sock);
  172.     return NIL;
  173.   }
  174.                 /* create TCP/IP stream */
  175.   stream = (TCPSTREAM *) fs_get (sizeof (TCPSTREAM));
  176.   stream->host = cpystr (host);    /* official host name */
  177.   stream->localhost = cpystr (mylocalhost ());
  178.   stream->port = port;        /* port number */
  179.   stream->tcps = sock;        /* init socket */
  180.   stream->ictr = 0;        /* init input counter */
  181.   return stream;        /* return success */
  182. }
  183.   
  184. /* TCP/IP authenticated open
  185.  * Accepts: host name
  186.  *        service name
  187.  *        returned user name
  188.  * Returns: TCP/IP stream if success else NIL
  189.  */
  190.  
  191. TCPSTREAM *tcp_aopen (char *host,char *service,char *usrnam)
  192. {
  193.   return NIL;            /* always NIL on DOS */
  194. }
  195.  
  196. /* TCP/IP receive line
  197.  * Accepts: TCP/IP stream
  198.  * Returns: text line string or NIL if failure
  199.  */
  200.  
  201. char *tcp_getline (TCPSTREAM *stream)
  202. {
  203.   int n,m;
  204.   char *st,*ret,*stp;
  205.   char c = '\0';
  206.   char d;
  207.                 /* make sure have data */
  208.   if (!tcp_getdata (stream)) return NIL;
  209.   st = stream->iptr;        /* save start of string */
  210.   n = 0;            /* init string count */
  211.   while (stream->ictr--) {    /* look for end of line */
  212.     d = *stream->iptr++;    /* slurp another character */
  213.     if ((c == '\015') && (d == '\012')) {
  214.       ret = (char *) fs_get (n--);
  215.       memcpy (ret,st,n);    /* copy into a free storage string */
  216.       ret[n] = '\0';        /* tie off string with null */
  217.       return ret;
  218.     }
  219.     n++;            /* count another character searched */
  220.     c = d;            /* remember previous character */
  221.   }
  222.                 /* copy partial string from buffer */
  223.   memcpy ((ret = stp = (char *) fs_get (n)),st,n);
  224.                 /* get more data from the net */
  225.   if (!tcp_getdata (stream)) return NIL;
  226.                 /* special case of newline broken by buffer */
  227.   if ((c == '\015') && (*stream->iptr == '\012')) {
  228.     stream->iptr++;        /* eat the line feed */
  229.     stream->ictr--;
  230.     ret[n - 1] = '\0';        /* tie off string with null */
  231.   }
  232.                 /* else recurse to get remainder */
  233.   else if (st = tcp_getline (stream)) {
  234.     ret = (char *) fs_get (n + 1 + (m = strlen (st)));
  235.     memcpy (ret,stp,n);        /* copy first part */
  236.     memcpy (ret + n,st,m);    /* and second part */
  237.     fs_give ((void **) &stp);    /* flush first part */
  238.     fs_give ((void **) &st);    /* flush second part */
  239.     ret[n + m] = '\0';        /* tie off string with null */
  240.   }
  241.   return ret;
  242. }
  243.  
  244. /* TCP/IP receive buffer
  245.  * Accepts: TCP/IP stream
  246.  *        size in bytes
  247.  *        buffer to read into
  248.  * Returns: T if success, NIL otherwise
  249.  */
  250.  
  251. long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *buffer)
  252. {
  253.   unsigned long n;
  254.   char *bufptr = buffer;
  255.   while (size > 0) {        /* until request satisfied */
  256.     if (!tcp_getdata (stream)) return NIL;
  257.     n = min (size,stream->ictr);/* number of bytes to transfer */
  258.                 /* do the copy */
  259.     memcpy (bufptr,stream->iptr,(size_t) n);
  260.     bufptr += n;        /* update pointer */
  261.     stream->iptr +=n;
  262.     size -= n;            /* update # of bytes to do */
  263.     stream->ictr -=n;
  264.   }
  265.   bufptr[0] = '\0';        /* tie off string */
  266.   return T;
  267. }
  268.  
  269.  
  270. /* TCP/IP receive data
  271.  * Accepts: TCP/IP stream
  272.  * Returns: T if success, NIL otherwise
  273.  */
  274.  
  275. long tcp_getdata (TCPSTREAM *stream)
  276. {
  277.   int status;
  278.   if (!stream->tcps) return NIL;/* no-no nuked socket */
  279.   while (stream->ictr < 1) {    /* if buffer empty, block for input and read */
  280.     if (!_ip_delay1 (stream->tcps,600,NULL,&status))
  281.       stream->ictr = sock_fastread (stream->tcps,
  282.                     stream->iptr = stream->ibuf,BUFLEN);
  283.     else if (status == 1) {    /* nuke the socket if closed */
  284.       sock_close (stream->tcps);
  285.       fs_give ((void **) &stream->tcps);
  286.       return NIL;
  287.     }
  288.   }
  289.   return T;
  290. }
  291.  
  292. /* TCP/IP send string as record
  293.  * Accepts: TCP/IP stream
  294.  * Returns: T if success else NIL
  295.  */
  296.  
  297. long tcp_soutr (TCPSTREAM *stream,char *string)
  298. {
  299.                 /* output the cruft */
  300.   sock_puts (stream->tcps,string);
  301.   return T;            /* all done */
  302. }
  303.  
  304.  
  305. /* TCP/IP send string
  306.  * Accepts: TCP/IP stream
  307.  *        string pointer
  308.  *        byte count
  309.  * Returns: T if success else NIL
  310.  */
  311.  
  312. long tcp_sout (TCPSTREAM *stream,char *string,unsigned long size)
  313. {
  314.   sock_write (stream->tcps,string,(int) size);
  315.   return T;
  316. }
  317.  
  318.  
  319. /* TCP/IP close
  320.  * Accepts: TCP/IP stream
  321.  */
  322.  
  323. void tcp_close (TCPSTREAM *stream)
  324. {
  325.   if (stream->tcps){         /* nuke the socket */
  326.     sock_close (stream->tcps);
  327.     _ip_delay2 (stream->tcps,0,NULL,NULL);
  328.   }
  329.   fs_give ((void **) &stream->tcps);
  330.                 /* flush host names */
  331.   fs_give ((void **) &stream->host);
  332.   fs_give ((void **) &stream->localhost);
  333.   fs_give ((void **) &stream);    /* flush the stream */
  334. }
  335.  
  336. /* TCP/IP get host name
  337.  * Accepts: TCP/IP stream
  338.  * Returns: host name for this stream
  339.  */
  340.  
  341. char *tcp_host (TCPSTREAM *stream)
  342. {
  343.   return stream->host;        /* return host name */
  344. }
  345.  
  346.  
  347. /* TCP/IP return port for this stream
  348.  * Accepts: TCP/IP stream
  349.  * Returns: port number for this stream
  350.  */
  351.  
  352. long tcp_port (TCPSTREAM *stream)
  353. {
  354.   return stream->port;        /* return port number */
  355. }
  356.  
  357.  
  358. /* TCP/IP get local host name
  359.  * Accepts: TCP/IP stream
  360.  * Returns: local host name
  361.  */
  362.  
  363. char *tcp_localhost (TCPSTREAM *stream)
  364. {
  365.   return stream->localhost;    /* return local host name */
  366. }
  367.